home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
glass
/
glass.lha
/
GLASS
/
tmc
/
cal.ct
< prev
next >
Wrap
Text File
|
1990-11-06
|
27KB
|
1,288 lines
/*
Copyright (C) 1990 C van Reewijk, email: dutentb.uucp!reeuwijk
This file is part of GLASS.
GLASS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
GLASS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLASS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
.. file: cal.ct
..
.. The following variables must be set in tm:
.. basename: the name of the module. used to generate init_.. and stat_..
.. wantdefs: the names of the wanted definitions.
.. OR
.. alldefs: All code.
..
.. The following C pre-processor variables must be defined:
.. STAT If you want code for statistics.
.. Statistics are written to 'FILE *statstream'.
.. FATAL(msg) If you want to supply a fatal error handler to print 'msg'.
.. A default is provided.
.. FIRSTROOM Initial room in lists. A default is provided.
..
.. Possible declaration or #define'ing of statstream must be done
.. outside this module.
.error Warning: 'cal' library is obsolete, use 'calu' library.
.error 'cal' does not support reading of NIL pointers.
.if ${index stat_$(basename) $(need_misc)}
.set statcode 1
.else
.set statcode 0
.endif
/* ---- start of ${tplfilename} ---- */
/* Routines for '$(basename)'.
template file: ${tplfilename}
datastructure file: ${dsfilename}
tm version: $(tmvers) ($(tmdate))
*/
/* used UNIX functions */
extern char *malloc();
extern char *realloc();
.if $(statcode)
#ifdef STAT
.foreach t $(need_stat_list)
static long newcnt_$t_list = 0;
static long frecnt_$t_list = 0;
static long hitcnt_$t_list = 0;
.endforeach
.foreach t $(need_stat)
.if ${strlen ${telmlist $t}}
static long newcnt_$t = 0;
static long frecnt_$t = 0;
static long hitcnt_$t = 0;
.else
.foreach c ${conslist $t}
static long newcnt_$c = 0;
static long frecnt_$c = 0;
static long hitcnt_$c = 0;
.endforeach
.endif
.endforeach
#endif
.endif
/* Caching variables.
*
* For each tuple, type list or constructor an array of
* CACHESZ elements is maintained that is filled by the fre_<type>()
* routines. If possible new_<type>() uses these elements.
* all cacheix_<type> variables maintain the index of the first
* free element in the array.
*/
#ifndef CACHESZ
#define CACHESZ 5
#endif
#ifdef USECACHE
#undef USECACHE
#endif
#if CACHESZ==0
#else
#define USECACHE
#endif
#ifdef USECACHE
.foreach t ${uniq $(need_new_list) $(need_fre_list)}
static short int cacheix_$t_list = 0;
static $t_list cache_$t_list[CACHESZ];
.endforeach
.foreach t ${uniq $(need_new) $(need_fre)}
.if ${strlen ${telmlist $t}}
static short int cacheix_$t = 0;
static $t cache_$t[CACHESZ];
.else
.foreach c ${conslist $t}
static short int cacheix_$c = 0;
static $c cache_$c[CACHESZ];
.endforeach
.endif
.endforeach
#endif
static char *tm_srcfile = __FILE__;
.if ${len $(need_print) $(need_print_list) $(need_fprint) $(need_fprint_list)}
static char tm_niltxt[] = "@";
.endif
.if $(statcode)
#ifdef STAT
static char tm_allocfreed[] = "%-15s: %6ld allocated, %6ld freed, %6ld cache hits.%s\n";
#endif
.endif
#ifndef FIRSTROOM
/* Default initial room in arrays. (uneducated guess). */
#define FIRSTROOM 2
#endif
#ifndef FATAL
#define FATAL(msg) tmfatal(tm_srcfile,__LINE__,msg)
#endif
#ifndef WORDBUFSIZE
#define WORDBUFSIZE 100
#endif
/* Possible error strings. */
static char tm_outofmemory[] = "out of memory";
.if ${strlen $(need_fscan)}
static char tm_badcons[] = "bad constructor for %s: '%s'";
.endif
.if ${strlen $(need_fscan_list)}
static char tm_badeof[] = "unexpected end of file";
.endif
#ifndef FATALTAG
#define FATALTAG(tag) tmbadtag(tm_srcfile,__LINE__,tag)
#endif
/* Forward declaration of local routines. */
/**************************************************
* array room routines *
**************************************************/
.foreach t $(need_room_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_room_list)
.set stic_$t
.endforeach
.foreach t $(need_room_list)
/* Announce that you will need room for 'rm' elements in
$t_list 'l'.
*/
$(stic_$t)void room_$t_list( l, rm )
register $t_list l;
register unsigned int rm;
{
if( l->room>rm ) return;
l->arr = ($t *) realloc( (char *) l->arr, rm * sizeof(*(l->arr)) );
if( l->arr == ($t *)0 ){
FATAL( tm_outofmemory );
}
l->room = rm;
}
.endforeach
/**************************************************
* Allocation routines *
**************************************************/
.foreach t $(need_new_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_new_list)
.set stic_$t
.endforeach
.foreach t $(need_new_list)
$(stic_$t)$t_list new_$t_list(){
$t_list new;
#ifdef USECACHE
if( cacheix_$t_list > 0 ){
new = cache_$t_list[--cacheix_$t_list];
.if $(statcode)
#ifdef STAT
hitcnt_$t_list++;
#endif
.endif
}
else {
#endif
new = ($t_list) malloc( sizeof(*new) );
if( (char *)new == (char *)0 ){
FATAL( tm_outofmemory );
}
#ifdef USECACHE
}
#endif
new->sz = 0;
new->arr = ($t *) malloc( FIRSTROOM*sizeof( *(new->arr) ) );
new->room = FIRSTROOM;
if( (char *)new->arr == (char *)0 ){
FATAL( tm_outofmemory );
}
.if $(statcode)
#ifdef STAT
newcnt_$t_list++;
#endif
.endif
return new;
}
.endforeach
.foreach t $(need_new)
.set stic_$t "static "
.endforeach
.foreach t $(want_new)
.set stic_$t
.endforeach
.foreach t $(need_new)
.if ${strlen ${telmlist $t}}
$(stic_$t)$t new_$t( ${seplist ", " ${prefix "p_" ${telmlist $t}}} )
.foreach sname ${telmlist $t}
.if ${eq list ${ttypeclass $t $(sname)}}
${ttypename $t $(sname)}_list p_$(sname);
.else
${ttypename $t $(sname)} p_$(sname);
.endif
.endforeach
{
register $t new;
#ifdef USECACHE
if( cacheix_$t > 0 ){
new = cache_$t[--cacheix_$t];
.if $(statcode)
#ifdef STAT
hitcnt_$t++;
#endif
.endif
}
else {
#endif
new = ($t) malloc( sizeof(*new));
if( (char *)new == (char *)0 ){
FATAL( tm_outofmemory );
}
#ifdef USECACHE
}
#endif
.foreach sname ${telmlist $t}
new->$(sname) = p_$(sname);
.endforeach
.if $(statcode)
#ifdef STAT
newcnt_$t++;
#endif
.endif
return new;
}
.else
.foreach c ${conslist $t}
$(stic_$t)$t new_$c( ${seplist ", " ${prefix "p_" ${celmlist $t $c}}} )
.foreach sname ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(sname)}}
${ctypename $t $c $(sname)}_list p_$(sname);
.else
${ctypename $t $c $(sname)} p_$(sname);
.endif
.endforeach
{
register $c new;
#ifdef USECACHE
if( cacheix_$c > 0 ){
new = cache_$c[--cacheix_$c];
.if $(statcode)
#ifdef STAT
hitcnt_$c++;
#endif
.endif
}
else {
#endif
new = ($c) malloc( sizeof(*new));
if( (char *)new == (char *)0 ){
FATAL( tm_outofmemory );
}
#ifdef USECACHE
}
#endif
new->tag = TAG$c;
.foreach sname ${celmlist $t $c}
new->$(sname) = p_$(sname);
.endforeach
.if $(statcode)
#ifdef STAT
newcnt_$c++;
#endif
.endif
return ($t) new;
}
.endforeach
.endif
.endforeach
/**************************************************
* Freeing routines *
**************************************************/
.foreach t $(need_fre)
.set stic_$t "static "
.endforeach
.foreach t $(want_fre)
.set stic_$t
.endforeach
.foreach t $(need_fre)
.if ${strlen ${telmlist $t}}
/* Free an element of type $t. */
$(stic_$t)void fre_$t( e )
$t e;
{
if( e == $tNIL ) return;
.if $(statcode)
#ifdef STAT
frecnt_$t++;
#endif
.endif
#ifdef USECACHE
if( cacheix_$t<CACHESZ ){
cache_$t[cacheix_$t++] = e;
return;
}
#endif
free( (char *) e );
}
.else
/* Free an element of type $t. */
$(stic_$t)void fre_$t( e )
$t e;
{
if( e == $tNIL ) return;
switch( e->tag ){
.foreach c ${conslist $t}
case TAG$c:
.if $(statcode)
#ifdef STAT
frecnt_$c++;
#endif
.endif
#ifdef USECACHE
if( cacheix_$c<CACHESZ ){
cache_$c[cacheix_$c++] = ($c) e;
break;
}
#endif
free( (char *) e );
break;
.endforeach
default:
FATALTAG( e->tag );
}
}
.endif
.endforeach
.foreach t $(need_fre_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_fre_list)
.set stic_$t
.endforeach
.foreach t $(need_fre_list)
/* Free a list of $t elements 'l'. */
$(stic_$t)void fre_$t_list( l )
$t_list l;
{
if( l == $t_listNIL ) return;
.if $(statcode)
#ifdef STAT
frecnt_$t_list++;
#endif
.endif
free( (char *) l->arr );
#ifdef USECACHE
if( cacheix_$t_list<CACHESZ ){
cache_$t_list[cacheix_$t_list++] = l;
return;
}
#endif
free( (char *) l );
}
.endforeach
/**************************************************
* Append routines *
**************************************************/
.foreach t $(need_app_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_app_list)
.set stic_$t
.endforeach
.foreach t $(need_app_list)
/* Append a '$t' element 'e' to list 'l'. */
$(stic_$t)void app_$t_list( l, e )
$t_list l;
$t e;
{
if( l->sz >= l->room )
room_$t_list( l, (l->sz)+(l->sz) );
l->arr[l->sz] = e;
l->sz++;
}
.endforeach
/**************************************************
* ins_<type>_list routines *
**************************************************/
.foreach t $(need_ins_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_ins_list)
.set stic_$t
.endforeach
.foreach t $(need_ins_list)
/* Insert a '$t' element 'e' into list 'l' at position 'pos'. */
$(stic_$t)void ins_$t_list( l, pos, e )
register $t_list l;
unsigned int pos;
$t e;
{
register unsigned int ix;
if( l->sz >= l->room ){
room_$t_list( l, (l->sz)+(l->sz) );
}
if( pos > l->sz ) pos = l->sz;
for( ix=l->sz; ix>pos; ix-- ){
l->arr[ix] = l->arr[ix-1];
}
l->sz++;
l->arr[pos] = e;
}
.endforeach
/**************************************************
* Concatenate routines *
**************************************************/
.foreach t $(need_conc_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_conc_list)
.set stic_$t
.endforeach
.foreach t $(need_conc_list)
/* Concatenate $t_list 'lb' after $t_list 'la'.
The list descriptor of 'lb' is freed,
since the contents has been moved to 'la'.
*/
$(stic_$t)void conc_$t_list( la, lb )
$t_list la;
$t_list lb;
{
register unsigned int cnt;
register $t *sp;
register $t *dp;
room_$t_list( la, la->sz+lb->sz );
cnt = lb->sz;
sp = lb->arr;
dp = &la->arr[la->sz];
while( cnt!=0 ){
*dp++ = *sp++;
cnt--;
}
la->sz += lb->sz;
fre_$t_list( lb );
}
.endforeach
/**************************************************
* Recursive freeing routines *
**************************************************/
.. Forward declarations
.foreach t $(need_rfre)
.if ${index $t $(want_rfre)}
.else
static void rfre_$t();
.endif
.endforeach
.foreach t $(need_rfre_list)
.if ${index $t $(want_rfre_list)}
.else
static void rfre_$t_list();
.endif
.endforeach
.foreach t $(need_rfre)
.set stic_$t "static "
.endforeach
.foreach t $(want_rfre)
.set stic_$t
.endforeach
.foreach t $(need_rfre)
/* Recursively free element 'e' of type '$t'
and all elements in it.
*/
.if ${strlen ${telmlist $t}}
$(stic_$t)void rfre_$t( e )
$t e;
{
if( e == $tNIL ) return;
.foreach sname ${telmlist $t}
.if ${eq list ${ttypeclass $t $(sname)}}
rfre_${ttypename $t $(sname)}_list( e->$(sname) );
.else
rfre_${ttypename $t $(sname)}( e->$(sname) );
.endif
.endforeach
fre_$t( e );
}
.else
$(stic_$t)void rfre_$t( e )
$t e;
{
if( e == $tNIL ) return;
switch( e->tag ){
.foreach c ${conslist $t}
case TAG$c:
.foreach sname ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(sname)}}
rfre_${ctypename $t $c $(sname)}_list( (($c) e)->$(sname) );
.else
rfre_${ctypename $t $c $(sname)}( (($c) e)->$(sname) );
.endif
.endforeach
break;
.endforeach
default:
FATALTAG( e->tag );
}
fre_$t( e );
}
.endif
.endforeach
.foreach t $(need_rfre_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_rfre_list)
.set stic_$t
.endforeach
.foreach t $(need_rfre_list)
/* Recursively free a list of elements 'e' of type $t. */
$(stic_$t)void rfre_$t_list( e )
$t_list e;
{
unsigned int ix;
if( e == $t_listNIL ) return;
for( ix=0; ix<e->sz; ix++ ) rfre_$t( e->arr[ix] );
fre_$t_list( e );
}
.endforeach
/**************************************************
* print_<type> and print_<type>_list routines *
**************************************************/
.. Forward declarations
.foreach t $(need_print)
.if ${index $t $(want_print)}
.else
static void print_$t();
.endif
.endforeach
.foreach t $(need_print_list)
.if ${index $t $(want_print_list)}
.else
static void print_$t_list();
.endif
.endforeach
.foreach t $(need_print)
.set stic_$t "static "
.endforeach
.foreach t $(want_print)
.set stic_$t
.endforeach
.foreach t $(need_print)
/* Print an element 't' of type '$t'
using print optimizer.
*/
$(stic_$t)void print_$t( t )
$t t;
{
.if ${strlen ${telmlist $t}}
if( t == $tNIL ){
printword( tm_niltxt );
return;
}
opentuple();
.foreach sname ${telmlist $t}
.if ${eq list ${ttypeclass $t $(sname)}}
print_${ttypename $t $(sname)}_list( t->$(sname) );
.else
print_${ttypename $t $(sname)}( t->$(sname) );
.endif
.endforeach
closetuple();
.else
if( t == $tNIL ){
printword( tm_niltxt );
return;
}
opencons();
switch( t->tag ){
.foreach c ${conslist $t}
case TAG$c:
printword( "$c" );
.foreach sname ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(sname)}}
print_${ctypename $t $c $(sname)}_list( (($c) t)->$(sname) );
.else
print_${ctypename $t $c $(sname)}( (($c) t)->$(sname) );
.endif
.endforeach
break;
.endforeach
default:
FATALTAG( t->tag );
}
closecons();
.endif
}
.endforeach
.foreach t $(need_print_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_print_list)
.set stic_$t
.endforeach
.foreach t $(need_print_list)
/* Print a list of elements 'l' of type '$t'
using print optimizer.
*/
$(stic_$t)void print_$t_list( l )
$t_list l;
{
unsigned int ix;
if( l == $t_listNIL ){
printword( tm_niltxt );
return;
}
openlist();
for( ix=0; ix<l->sz; ix++ ) print_$t( l->arr[ix] );
closelist();
}
.endforeach
/***************************************************
* fprint_<type> and fprint_<type>_list routines *
***************************************************/
.. Forward declarations
.foreach t $(need_fprint)
.if ${index $t $(want_fprint)}
.else
static void fprint_$t();
.endif
.endforeach
.foreach t $(need_fprint_list)
.if ${index $t $(want_fprint_list)}
.else
static void fprint_$t_list();
.endif
.endforeach
.foreach t $(need_fprint)
.set stic_$t "static "
.endforeach
.foreach t $(want_fprint)
.set stic_$t
.endforeach
.foreach t $(need_fprint)
/* Print an element 't' of type '$t'
to file 'f'.
*/
$(stic_$t)void fprint_$t( f, t )
FILE *f;
$t t;
{
if( t == $tNIL ){
fprintf( f, tm_niltxt );
return;
}
putc( '(', f );
.if ${strlen ${telmlist $t}}
.set first 1
.foreach sname ${telmlist $t}
.if $(first)
.set first 0
.else
putc( ',', f );
.endif
.if ${eq list ${ttypeclass $t $(sname)}}
fprint_${ttypename $t $(sname)}_list( f, t->$(sname) );
.else
fprint_${ttypename $t $(sname)}( f, t->$(sname) );
.endif
.endforeach
.else
switch( t->tag ){
.foreach c ${conslist $t}
case TAG$c:
fputs( "$c", f );
.foreach sname ${celmlist $t $c}
putc( ' ', f );
.if ${eq list ${ctypeclass $t $c $(sname)}}
fprint_${ctypename $t $c $(sname)}_list( f, (($c) t)->$(sname) );
.else
fprint_${ctypename $t $c $(sname)}( f, (($c) t)->$(sname) );
.endif
.endforeach
break;
.endforeach
default:
FATALTAG( t->tag );
}
.endif
fputs( ")\n", f );
}
.endforeach
.foreach t $(need_fprint_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_fprint_list)
.set stic_$t
.endforeach
.foreach t $(need_fprint_list)
/* Print a list of elements 'l' of type '$t'
to file 'f'.
*/
$(stic_$t)void fprint_$t_list( f, l )
FILE *f;
$t_list l;
{
register unsigned int ix;
if( l == $t_listNIL ){
fprintf( f, tm_niltxt );
return;
}
putc( '[', f );
for( ix=0; ix<l->sz; ix++ ){
if( ix!=0 ){
fputc( ',', f );
}
fprint_$t( f, l->arr[ix] );
}
fputs( "]\n", f );
}
.endforeach
/**************************************************
* Duplication routines *
**************************************************/
.. Forward declarations
.foreach t $(need_rdup)
.if ${index $t $(want_rdup)}
.else
static $t rdup_$t();
.endif
.endforeach
.foreach t $(need_rdup_list)
.if ${index $t $(want_rdup_list)}
.else
static $t_list rdup_$t_list();
.endif
.endforeach
.foreach t $(need_rdup)
.set stic_$t "static "
.endforeach
.foreach t $(want_rdup)
.set stic_$t
.endforeach
.foreach t $(need_rdup)
/* Recursively duplicate instance 'e' of type '$t' and
* all elements in it.
*/
$(stic_$t)$t rdup_$t( e )
$t e;
{
.if ${strlen ${telmlist $t}}
.foreach e ${telmlist $t}
.if ${eq list ${ttypeclass $t $e}}
${ttypename $t $e}_list i_$e;
.else
${ttypename $t $e} i_$e;
.endif
.endforeach
if( e == $tNIL ) return $tNIL;
.foreach e ${telmlist $t}
.if ${eq list ${ttypeclass $t $e}}
i_$e = rdup_${ttypename $t $e}_list( e->$e );
.else
i_$e = rdup_${ttypename $t $e}( e->$e );
.endif
.endforeach
return new_$t( ${seplist ", " ${prefix "i_" ${telmlist $t}}} );
.else
if( e == $tNIL ) return $tNIL;
switch( e->tag ){
.foreach c ${conslist $t}
case TAG$c:
{
.foreach e ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $e}}
${ctypename $t $c $e}_list i_$e;
.else
${ctypename $t $c $e} i_$e;
.endif
.endforeach
.foreach e ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $e}}
i_$e = rdup_${ctypename $t $c $e}_list( (($c) e)->$e );
.else
i_$e = rdup_${ctypename $t $c $e}( (($c) e)->$e );
.endif
.endforeach
return new_$c( ${seplist ", " ${prefix "i_" ${celmlist $t $c}}} );
}
.endforeach
default:
FATALTAG( e->tag );
}
return $tNIL;
.endif
}
.endforeach
.foreach t $(need_rdup_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_rdup_list)
.set stic_$t
.endforeach
.foreach t $(need_rdup_list)
/* Recursively duplicate an instance 'e' of a '$t' list */
$(stic_$t)$t_list rdup_$t_list( e )
$t_list e;
{
unsigned int ix;
$t_list new;
new = new_$t_list();
room_$t_list( new, e->sz );
for( ix=0; ix<e->sz; ix++ ){
app_$t_list( new, rdup_$t( e->arr[ix] ) );
}
return new;
}
.endforeach
/*********************************************************
* cmp_<type> and cmp_<type>_list routines *
*********************************************************/
.. Forward declarations
.foreach t $(need_cmp)
.if ${index $t $(want_cmp)}
.else
static int cmp_$t();
.endif
.endforeach
.foreach t $(need_cmp_list)
.if ${index $t $(want_cmp_list)}
.else
static int cmp_$t_list();
.endif
.endforeach
.foreach t $(need_cmp)
.if ${index $t $(want_cmp)}
.set stat
.else
.set stat "static "
.endif
.if ${len ${telmlist $t}}
.. cmp tuple
/* Compare two $t tuples 'a' and 'b'. */
$(stat)int cmp_$t( a, b )
register $t a;
register $t b;
{
register int res;
res = 0;
.set first 1
.foreach ename ${telmlist $t}
.if ${eq list ${ttypeclass $t $(ename)}}
.set tn ${ttypename $t $(ename)}_list
.else
.set tn ${ttypename $t $(ename)}
.endif
.if $(first)
.set first 0
.else
if( res != 0 ) return res;
.endif
res = cmp_$(tn)( a->$(ename), b->$(ename) );
.endforeach
return res;
}
.else
.. cmp constructor
/* Compare two $t constructors 'a' and 'b'. */
$(stat)int cmp_$t( a, b )
$t a;
$t b;
{
register int res;
res = ((int)a->tag - (int)b->tag);
if( res != 0 ) return res;
switch( a->tag )
{
.foreach c ${conslist $t}
case TAG$c:
.set first 1
.foreach ename ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(ename)}}
.set tn ${ctypename $t $c $(ename)}_list
.else
.set tn ${ctypename $t $c $(ename)}
.endif
.if $(first)
.set first 0
.else
if( res != 0 ) break;
.endif
res = cmp_$(tn)( (($c) a)->$(ename), (($c) b)->$(ename) );
.endforeach
break;
.endforeach
default:
FATALTAG( a->tag );
}
return res;
}
.endif
.endforeach
.foreach t $(need_cmp_list)
.if ${index $t $(want_cmp_list)}
.set stat
.else
.set stat "static "
.endif
/* Compare two $t lists 'a' and 'b'. */
$(stat)int cmp_$t_list( a, b )
register $t_list a;
register $t_list b;
{
register int res;
register unsigned int ix;
ix = 0;
while( ix<a->sz || ix<b->sz ){
if( ix>=a->sz ) return -1;
if( ix>=b->sz ) return 1;
res = cmp_$t( a->arr[ix], b->arr[ix] );
if( res != 0 ) return res;
ix++;
}
return 0;
}
.endforeach
/**************************************************
* Scan routines *
**************************************************/
.. Forward declarations
.foreach t $(need_fscan)
.if ${index $t $(want_fscan)}
.else
static int fscan_$t();
.endif
.endforeach
.foreach t $(need_fscan_list)
.if ${index $t $(want_fscan_list)}
.else
static int fscan_$t_list();
.endif
.endforeach
.foreach t $(need_fscan)
.set stic_$t "static "
.endforeach
.foreach t $(want_fscan)
.set stic_$t
.endforeach
.foreach t $(need_fscan)
.if ${strlen ${telmlist $t}}
/* Read a tuple of type $t
from file 'f' and allocate space for it.
Set the pointer 'p' to point to that structure.
*/
$(stic_$t)int fscan_$t( f, p )
FILE *f;
$t *p;
{
register short int err;
.foreach ename ${telmlist $t}
.if ${eq list ${ttypeclass $t $(ename)}}
.set tn ${ttypename $t $(ename)}_list
.else
.set tn ${ttypename $t $(ename)}
.endif
$(tn) l_$(ename);
.endforeach
.foreach ename ${telmlist $t}
.if ${eq list ${ttypeclass $t $(ename)}}
.set tn ${ttypename $t $(ename)}_list
.else
.set tn ${ttypename $t $(ename)}
.endif
l_$(ename) = $(tn)NIL;
.endforeach
err = tmfneedc( f, '(' );
if( err ) return 1;
.set first 1
.foreach ename ${telmlist $t}
.if ${eq list ${ttypeclass $t $(ename)}}
.set tn ${ttypename $t $(ename)}_list
.else
.set tn ${ttypename $t $(ename)}
.endif
.if $(first)
.set first 0
.else
if( !err ) err = tmfneedc( f, ',' );
.endif
if( !err ) err = fscan_$(tn)( f, &l_$(ename) );
.endforeach
*p = new_$t( ${seplist ", " ${prefix " l_" ${telmlist $t}}} );
if( err ) return 1;
return tmfneedc( f, ')' );
}
.else
/* Read an instance of a datastructure of type $t.
from file 'f' and allocate space for it. Set the pointer 'p' to
point to that structure.
*/
$(stic_$t)int fscan_$t( f, p )
FILE *f;
$t *p;
{
register int n;
char tm_word[WORDBUFSIZE];
register short int err = 0;
n = fscanopenbrac( f );
if( fscancons( f, tm_word ) ){
*p = $tNIL;
return 1;
}
.. First time in loop there should be no 'else' before the if,
.. in all other cases there should.
.set els
.foreach c ${conslist $t}
$(els)if( strcmp( tm_word, "$c" ) == 0 ){
.foreach ename ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(ename)}}
.set tn ${ctypename $t $c $(ename)}_list
.else
.set tn ${ctypename $t $c $(ename)}
.endif
$(tn) l_$(ename);
.endforeach
.foreach ename ${celmlist $t $c}
.if ${eq list ${ctypeclass $t $c $(ename)}}
.set tn ${ctypename $t $c $(ename)}_list
.else
.set tn ${ctypename $t $c $(ename)}
.endif
l_$(ename) = $(tn)NIL;
if( !err) err = fscan_$(tn)( f, &l_$(ename) );
.endforeach
*p = new_$c( ${seplist ", " ${prefix " l_" ${celmlist $t $c}}} );
}
.set els "else "
.endforeach
else {
(void) sprintf( tmerrmsg, tm_badcons, "$t", tm_word );
return 1;
}
if( err ) return 1;
return fscanclosebrac( f, n );
}
.endif
.endforeach
.foreach t $(need_fscan_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_fscan_list)
.set stic_$t
.endforeach
.foreach t $(need_fscan_list)
/* Read an instance of a list of datastructure of type $t.
from file 'f' and allocate space for it. Set the pointer 'p' to
point to that structure.
*/
$(stic_$t)int fscan_$t_list( f, p )
FILE *f;
$t_list *p;
{
register short int err = 0;
register int c;
int n;
$t new;
*p = new_$t_list();
n = fscanopenbrac( f );
if( tmfneedc( f, '[' ) ) return 1;
if( fscanspace( f ) ) return 1;
c = getc( f );
if( c == ']' ) return 0;
if( c == EOF ){
(void) strcpy( tmerrmsg, tm_badeof );
return 1;
}
ungetc( c, f );
while( 1 ){
if( !err ) err = fscan_$t( f, &new );
app_$t_list( *p, new );
if( err || fscanspace( f ) ) return 1;
c = getc( f );
if( c == EOF ){
(void) strcpy( tmerrmsg, tm_badeof );
return 1;
}
if( c != ',' ){
ungetc( c, f );
break;
}
}
if( tmfneedc( f, ']' ) ) return 1;
return fscanclosebrac( f, n );
}
.endforeach
/**************************************************
* del_<type>_list routines *
**************************************************/
.foreach t $(need_del_list)
.set stic_$t "static "
.endforeach
.foreach t $(want_del_list)
.set stic_$t
.endforeach
.foreach t $(need_del_list)
/* Delete '$t' element at position 'pos' in list 'l'. */
$(stic_$t)void del_$t_list( l, pos )
register $t_list l;
unsigned int pos;
{
register unsigned int ix;
if( pos >= l->sz ) return;
rfre_$t( l->arr[pos] );
l->sz--;
for( ix=pos; ix<l->sz; ix++ ){
l->arr[ix] = l->arr[ix+1];
}
}
.endforeach
/************************************************************
* Miscellaneous routines *
************************************************************/
.if ${index flush_$(basename) $(need_misc)}
/* Flush the allocation caches. */
void flush_$(basename)()
{
#ifdef USECACHE
register short int ix;
.foreach t ${uniq $(need_new_list) $(need_fre_list)}
for( ix=0; ix<cacheix_$t_list; ix++ ){
free( (char *) cache_$t_list[ix] );
}
cacheix_$t_list = 0;
.endforeach
.foreach t ${uniq $(need_new) $(need_fre)}
.if ${strlen ${telmlist $t}}
for( ix=0; ix<cacheix_$t; ix++ ){
free( (char *) cache_$t[ix] );
}
cacheix_$t = 0;
.else
.foreach c ${conslist $t}
for( ix=0; ix<cacheix_$c; ix++ ){
free( (char *) cache_$c[ix] );
}
cacheix_$c = 0;
.endforeach
.endif
.endforeach
#endif
}
.endif
.if $(statcode)
/* Give statistics. */
void stat_$(basename)( f )
FILE *f;
{
#ifdef STAT
.foreach t $(need_stat_list)
fprintf( f, tm_allocfreed, "[$t]", newcnt_$t_list, frecnt_$t_list, hitcnt_$t_list, ((newcnt_$t_list==frecnt_$t_list)? "": "<-") );
.endforeach
.foreach t $(need_stat)
.if ${strlen ${telmlist $t}}
fprintf(f,tm_allocfreed,"$t",newcnt_$t,frecnt_$t,hitcnt_$t,((newcnt_$t==frecnt_$t)? "": "<-") );
.else
.foreach c ${conslist $t}
fprintf(f,tm_allocfreed,"$c",newcnt_$c,frecnt_$c,hitcnt_$c,((newcnt_$c==frecnt_$c)? "": "<-") );
.endforeach
.endif
.endforeach
#else
f = f; /* to prevent 'f unused' from compiler and lint */
#endif
}
.endif
/* ---- end of ${tplfilename} ---- */